import { defineConfig, loadEnv, type UserConfig, type ConfigEnv } from "vite"
import { autoComplete, Plugin as ImportToCDN } from "vite-plugin-cdn-import";
import react from '@vitejs/plugin-react'
import reactRefresh from '@vitejs/plugin-react-refresh';
import { resolve } from "node:path";
import WebSocket, { WebSocketServer } from "ws";
import chokidar from "chokidar"
import fs from 'fs'
const vitePluginBuildWatch = (port: number) => {
  let wsClient: WebSocket | null
  let socketServe: WebSocketServer | null

  const send = (msg: string) => {
    if (!wsClient) return;
    wsClient.send(msg);
  }

  const close = () => {
    wsClient && wsClient.close();
    wsClient = null;
    socketServe = null;
  }

  return {
    name: 'vite-plugin-build-watch',
    apply: (config: UserConfig, { command }: ConfigEnv) => {
      const canUse = command === 'build' && Boolean(config.build?.watch)
      // build --watch 模式下生效
      if (canUse) {
        socketServe = new WebSocketServer({ port });
        socketServe.on('connection', (client) => {
          wsClient = client
        });
        // 监听public manifest文件的变动
        const watcher = chokidar.watch('./public')

        watcher.on('all', (_event, path) => {
          if (path.includes('manifest')) {
            const dest = resolve(`./dist/${path.split('/')[1]}`)
            fs.copyFileSync(path, dest)
            send('reload-app')
          }
        })
      }
      return canUse;
    },
    closeBundle: () => send('reload-window'),
    closeWatcher: () => close()
  }
}
export default defineConfig(({ mode}): UserConfig => {
  const env = loadEnv(mode, "./env");
  const isDev = env.VITE_PROJECT_ENV !== 'production';
  const port = env.VITE_HMR_PORT;
  const plugins = [
    react(),
    reactRefresh(),
    ImportToCDN({
      prodUrl: 'https://cdn.jsdelivr.net/npm/{name}@{version}/{path}',
      modules: [
        autoComplete('react'),
        autoComplete('react-dom'),
        autoComplete('axios')
      ]
    })
  ];
  isDev && plugins.push(vitePluginBuildWatch(Number(port)));
  return {
    envDir: "./env",
    base: './',
    plugins,
    esbuild: {
      drop: !isDev ? ['console', 'debugger'] : []
    },
    resolve: {
      alias: [{
        find: '@',
        replacement: resolve('./src')
      }],
      extensions: [".js", ".ts", ".tsx", ".scss", '.css']
    },
    css: {
      preprocessorOptions: {
        scss: {
          additionalData: `@import "@/styles/variables.scss"; @import "@/styles/mixins.scss";`
        }
      }
    },
    build: {
      target: 'ESNEXT',
      rollupOptions: {
        input: {
          popup: resolve('./index.html'),
          background: resolve('./src/background/index.ts'),
          content: resolve('./src/content/index.ts')
        },
        output: {
          entryFileNames: '[name].js',
          chunkFileNames: "assets/js/[name].js",
          assetFileNames: "assets/[ext]/[name].[ext]",
        }
      }
    },
    server: {
      port: 8080,
      open: "/",
      host: true,
      proxy: {
        "/tr": {
          target: env.VITE_TRANSLATE_URL,
          changeOrigin: true,
          rewrite: path => path.replace(/^\/tr/, "")
        }
      }
    }
  }
})
